﻿using System;

using UnityEngine;
//List依赖
using System.Collections.Generic;
//Random依赖
using Random = UnityEngine.Random;

public class BoardManager : MonoBehaviour {
    //设定计数用类
    [Serializable]
    public class Count {
        public int minimum;
        public int maximum;

        public Count (int min, int max) {
            minimum = min;
            maximum = max;
        }
    }

    //制作8*8的游戏棋盘
    //纵8格
    public int columns = 8;
    //横8格
    public int rows = 8;
    //墙壁5〜9之间随机刷新
    public Count wallCount = new Count (5, 9);
    //道具1〜5之間随机刷新
    public Count foodCount = new Count (1, 5);
    //Exit对象
    public GameObject exit;
    //配置复数地板・内壁・道具・敌人角色・外墙壁的数组
    public GameObject [ ] floorTiles;
    public GameObject [ ] wallTiles;
    public GameObject [ ] foodTiles;
    public GameObject [ ] enemyTiles;
    public GameObject [ ] outerWallTiles;

    //保存对象的位置信息的变量(生成物体相对的基准坐标)
    private Transform boardHolder;
    //用来记录对象可以配置范围的列表
    //使用List是因为可变其长度
    private List<Vector3> gridPositions = new List<Vector3> ( );

    //决定可以配置敌人角色・道具・内壁的范围
    void InitialiseList ( ) {
        //清空gridPosition
        gridPositions.Clear ( );
        //gridPosition填充可能配置的范围
        //x = 1〜6循环
        for (int x = 1; x < columns - 1; x++) {
            //y = 1〜6循环
            for (int y = 1; y < rows - 1; y++) {
                //6*6的范围中填充gridPositions
                gridPositions.Add (new Vector3 (x, y, 0f));
            }
        }
    }
    // 配置外壁、地板
    void BoardSetup ( ) {
        //生成名为Board的对象、transform信息保存到boardHolder
        boardHolder = new GameObject ("Board").transform;
        //x = -1〜8循环
        for (int x = -1; x < columns + 1; x++) {
            //y = -1〜8循环
            for (int y = -1; y < rows + 1; y++) {
                //随机选择地板
                GameObject toInstantiate = floorTiles [Random.Range (0, floorTiles.Length)];
                //左端or右端or最低部or最上部＝生成外壁的时机
                if (x == -1 || x == columns || y == -1 || y == rows) {
                    //与floorTile相同随机选择外壁，因为不需要地板了，所以覆盖掉地板
                    toInstantiate = outerWallTiles [Random.Range (0, outerWallTiles.Length)];
                }
                //生成地板or外壁、保存到instance变量
                GameObject instance = Instantiate (toInstantiate, new Vector3 (x, y, 0f),
                    Quaternion.identity) as GameObject;
                //生成的instance作为Board对象的子对象
                instance.transform.SetParent (boardHolder);
            }
        }
    }

    // 场景中的随机坐标
    Vector3 RandomPosition ( ) {
        //0〜36(gridPositions的长度)中随机选择决定一个位置
        int randomIndex = Random.Range (0, gridPositions.Count);
        Vector3 randomPosition = gridPositions [randomIndex];
        //把选择过的位置删除
        gridPositions.RemoveAt (randomIndex);
        //返回决定的位置
        return randomPosition;
    }

    // 随机生成对象
    void LayoutObjectAtRandom (GameObject [ ] tileArray, int minimum, int maximum) {
        //进行最小値〜最大値+1的随机回数循环
        int objectCount = Random.Range (minimum, maximum + 1);
        for (int i = 0; i < objectCount; i++) {
            //从gridPosition获取一个位置
            Vector3 randomPosition = RandomPosition ( );
            //从参数tileArray中随机选择一个游戏对象
            GameObject tileChoise = tileArray [Random.Range (0, tileArray.Length)];
            //从随机选择的种类・位置中生成
            Instantiate (tileChoise, randomPosition, Quaternion.identity);
        }
    }
    //配置对象方法
    //这个类中唯一的public方法 关系到地板生成时机所以从GameManager中调用
    public void SetupScene (int level) {
        //地板和墙壁
        BoardSetup ( );
        //决定能够敌人角色・内壁・道具配置的位置
        InitialiseList ( );
        //内壁・道具・敌方角色 随机进行配置、
        LayoutObjectAtRandom (wallTiles, wallCount.minimum, wallCount.maximum);
        LayoutObjectAtRandom (foodTiles, foodCount.minimum, foodCount.maximum);
        //Mathf.Log : 计算以2为底的对数。level=4是2、level=8是3
        int enemyCount = (int) Mathf.Log (level, 2f);
        LayoutObjectAtRandom (enemyTiles, enemyCount, enemyCount);
        //将Exit配置到7, 7的位置。
        Instantiate (exit, new Vector3 (columns - 1, rows - 1, 0F), Quaternion.identity);
    }
}
